#include "experimentmethodui.h"
#include "ui_experimentmethodui.h"
#include "ui_stagestep.h"

ExperimentMethodUi::ExperimentMethodUi(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ExperimentMethodUi)
{
    ui->setupUi(this);

    /* 初始化变量 */
    procedureService = new ProcedureService();
    cusMsg = new CustomMessageBox();
    this->cyclingNumber = 40;

    /* 右滚动箭头定时器 */
    connect(ui->rightArr, &QPushButton::clicked, this, [=](){
        /* 获取滚动条的值 */
        procedureScrollBarValue = ui->stageWidget->horizontalScrollBar()->value();
        if(procedureScrollBarValue < ui->stageWidget->horizontalScrollBar()->maximum()){
            procedureScrollBarValue += 202;
            ui->stageWidget->horizontalScrollBar()->setValue(procedureScrollBarValue);
        }
    });

    /* 左滚动箭头定时器 */
    connect(ui->leftArr, &QPushButton::clicked, this, [=](){
        /* 获取滚动条的值 */
        procedureScrollBarValue = ui->stageWidget->horizontalScrollBar()->value();
        if(procedureScrollBarValue > 0){
            procedureScrollBarValue -= 202;
            ui->stageWidget->horizontalScrollBar()->setValue(procedureScrollBarValue);
        }
    });

    /* 重置扩增 */
    connect(ui->resetProcedure, &QPushButton::clicked, this, [=](){
        this->resetProcedure(id);
    });
    /* 上一步按钮 */
    connect(ui->previousBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentMethodUi::previousEvent();
    });

    /* 下一步按钮 */
    connect(ui->nextBtn, &QPushButton::clicked, this, &ExperimentMethodUi::nextCallback);

    /* 保存按钮 */
    connect(ui->saveBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentMethodUi::saveEvent();
    });

    /* 扩增页面弹簧 */
    hSpacer = new QSpacerItem(20, 40, QSizePolicy::Expanding);
    ui->stageWidgetLayout->addItem(hSpacer);
}

ExperimentMethodUi::~ExperimentMethodUi()
{
    delete ui;
}

/* 下一步 */
void ExperimentMethodUi::nextCallback(){
    emit ExperimentMethodUi::nextEvent();
}

/* 返回数据信息 */
std::tuple<int, int, int, int, int> ExperimentMethodUi::returnPageInfos(){
    std::tuple<int, int, int, int, int> pageInfos;
    pageInfos = std::make_tuple(
                ui->liquidVolume->value(),
                this->stepCount,
                this->stageCount,
                this->totalrunningTime,
                this->cyclingNumber);
    return pageInfos;
}

/* 获取扩增阶段所需数据 */
void ExperimentMethodUi::getMethodData(QString id, QString experimentType){
    this->id = id;
    this->experimentType = experimentType;
}

/* 创建扩增步骤 */
void ExperimentMethodUi::createStep(QHBoxLayout* parent, ProcedureStep stepInfo, QString expId, QString index){
    StageStep *s = new StageStep();
    bool marked = (stepInfo.is_fluorescence == "1");

    s->ui->holdStageController->blockSignals(true);

    s->ui->finalTempInput->setText(stepInfo.temperature);
    s->ui->raiseTempSpeedInput->setText(stepInfo.rate);
    s->ui->runningTimeHour->setText(QString::number((stepInfo.duration.toInt())/60));
    s->ui->runningTimeMin->setText((QString::number(stepInfo.duration.toInt() - ((stepInfo.duration.toInt())/60)*60)));
    s->ui->stepOrder->setText("步骤" + stepInfo.step_order);
    s->ui->holdStageController->setValue(stepInfo.temperature.toDouble()*10);
    s->setObjectName("step");

    if(!marked){
        s->ui->dataCollection->setIcon(QIcon(":/image/image/unmarked"));
    }
    else {
        s->ui->dataCollection->setIcon(QIcon(":/image/image/marked"));
    }
    parent->insertWidget(index.toInt(), s);

    s->ui->holdStageController->blockSignals(false);

    /* 温度改变，重新计算温差，计算预计时间 */
    connect(s->ui->holdStageController, &QSlider::valueChanged, this, &ExperimentMethodUi::viaTempMinusToCalculateTime);

    connect(s->ui->dataCollection, &QPushButton::clicked, this, [=]() mutable{
        marked = !marked;
        if(!marked){
            s->ui->dataCollection->setIcon(QIcon(":/image/image/unmarked"));
            procedureService->openFluorescence(stepInfo.stage_id, stepInfo.step_order, marked);
        }
        else{
            s->ui->dataCollection->setIcon(QIcon(":/image/image/marked"));
            procedureService->openFluorescence(stepInfo.stage_id, stepInfo.step_order, marked);
        }
    });

    connect(s->ui->leftAddStep, &MethodMoveButton::clicked, this, [=](){
        ProcedureStep step;
        step.temperature = "50";
        step.rate = "2";
        step.duration = "50";
        step.is_fluorescence = "0";
        step.step_order = stepInfo.step_order;
        step.stage_id = stepInfo.stage_id;
        s->setObjectName("step");
        procedureService->insertStep(step);
        this->renderProcedure(expId);
    });
    connect(s->ui->rightAddStep, &MethodMoveButton::clicked, this, [=](){
        ProcedureStep step;
        step.temperature = "50";
        step.rate = "2";
        step.duration = "50";
        step.is_fluorescence = "0";
        step.step_order = QString::number(stepInfo.step_order.toInt()+1);
        step.stage_id = stepInfo.stage_id;
        s->setObjectName("step");
        procedureService->insertStep(step);
        this->renderProcedure(expId);
    });
    connect(s->ui->deleteStep, &MethodMoveButton::clicked, this, [=](){
        if(stepCount == 1){
            s->ui->deleteStep->setEnabled(false);
            return;
        }

        procedureService->deleteStep(stepInfo.stage_id, stepInfo.step_order);
        this->renderProcedure(expId);
    });

    connect(s->ui->raiseTempSpeedInput, &QLineEdit::editingFinished, this, [=](){
        /* 最大值校验 */
        if(s->ui->raiseTempSpeedInput->displayText().toDouble() > 20.0){
            s->ui->raiseTempSpeedInput->setText("20.0");
            procedureService->updateRate(stepInfo.stage_id, stepInfo.step_order, "20.0");
        }
        /* 最小值校验 */
        else if(s->ui->raiseTempSpeedInput->displayText().toDouble() < 0.1){
            s->ui->raiseTempSpeedInput->setText("0.1");
            procedureService->updateRate(stepInfo.stage_id, stepInfo.step_order, "0.1");
        }
        /* 都不是，将新数据写入数据库 */
        else {
            procedureService->updateRate(stepInfo.stage_id, stepInfo.step_order, s->ui->raiseTempSpeedInput->displayText());
        }

    });
    connect(s->ui->raiseTempSpeedInput, &QLineEdit::textChanged, this, [=](){
        LOG << "raiseTempSpeedInput changed";

        /* 空值校验 */
        if(s->ui->raiseTempSpeedInput->displayText() == ""){
            s->ui->raiseTempSpeedInput->setText("0.1");
            s->ui->raiseTempSpeedInput->selectAll();
            procedureService->updateRate(stepInfo.stage_id, stepInfo.step_order, "0.1");
        }
    });

    connect(s->ui->finalTempInput, &QLineEdit::editingFinished, this, [=](){
        /* 空值校验 */
        if(s->ui->finalTempInput->displayText() == ""){
            s->ui->finalTempInput->setText("40");
            s->ui->finalTempInput->selectAll();
            s->ui->holdStageController->setValue(400);
        }
        /* 最小值校验 */
        if(s->ui->finalTempInput->displayText().toDouble() < 40.0){
            s->ui->holdStageController->setValue(400);
            s->ui->finalTempInput->setText("40.0");
        }
        /* 最大值校验 */
        else if(s->ui->finalTempInput->displayText().toDouble() > 100.0){
            s->ui->holdStageController->setValue(1000);
            s->ui->finalTempInput->setText("100.0");
        }
        else {
            s->ui->holdStageController->setValue(s->ui->finalTempInput->displayText().toDouble()*10);
        }
        procedureService->updateTemperature(stepInfo.stage_id, stepInfo.step_order, s->ui->finalTempInput->displayText());
    });

    connect(s->ui->holdStageController, &QSlider::valueChanged, this, [=](int temp){
        s->ui->finalTempInput->setText(QString::number(temp/10.0));
        procedureService->updateTemperature(stepInfo.stage_id, stepInfo.step_order, s->ui->finalTempInput->displayText());
    });

    connect(s->ui->runningTimeMin, &QLineEdit::textChanged, this, [=](QString text){
        int totalTime;
        /* 最大值校验 */
        if(text.toInt() > 59){
            s->ui->runningTimeMin->setText("59");
            totalTime = s->ui->runningTimeHour->displayText().toInt()*60 + 59;
        }
        /* 空值校验 */
        else if(text == "") {
            s->ui->runningTimeMin->setText("0");
            totalTime = s->ui->runningTimeHour->displayText().toInt()*60;
        }
        else {
            s->ui->runningTimeMin->setText(QString::number(0+text.toInt()));
            totalTime = s->ui->runningTimeHour->displayText().toInt()*60 + text.toInt();
        }

        procedureService->updateDuration(stepInfo.stage_id, stepInfo.step_order, QString::number(totalTime));
        this->viaTempMinusToCalculateTime();
        });

    connect(s->ui->runningTimeHour, &QLineEdit::textChanged, this, [=](QString text){
        int totalTime;
        /* 最大值校验 */
        if(text.toInt() > 99){
            s->ui->runningTimeHour->setText("99");
            totalTime = 99*60 + s->ui->runningTimeMin->displayText().toInt();
        }
        /* 空值校验 */
        else if(text == "") {
            s->ui->runningTimeHour->setText("0");
            totalTime = s->ui->runningTimeMin->displayText().toInt();
        }
        else {
            s->ui->runningTimeHour->setText(QString::number(0+text.toInt()));
            totalTime = text.toInt()*60 + s->ui->runningTimeMin->displayText().toInt();
        }

        procedureService->updateDuration(stepInfo.stage_id, stepInfo.step_order, QString::number(totalTime));
        this->viaTempMinusToCalculateTime();
    });
}

/* 创建扩增阶段 */
std::tuple<QHBoxLayout*, QWidget*, QString> ExperimentMethodUi::createNewStage(QString expId, QString cyclingNumber, QString stageName, QString stageOrder, QString stageId){
    ui->stageWidgetLayout->removeItem(hSpacer);
    QWidget *stage = new QWidget();
    QWidget *stepContainer = new QWidget();
    QWidget *footer = new QWidget();
    QWidget *cyclingContainer = new QWidget();
    QWidget *addStageContainer = new QWidget();
    QHBoxLayout *h = new QHBoxLayout();
    QHBoxLayout *hFooter = new QHBoxLayout();
    QVBoxLayout *v = new QVBoxLayout();
    QHBoxLayout *footerLayout = new QHBoxLayout();
    QHBoxLayout *addStageBtnLayout = new QHBoxLayout();
    QPushButton *leftAddStage = new QPushButton();
    QPushButton *rightAddStage = new QPushButton();
    QPushButton *deleteStage = new QPushButton();
    QLabel *title = new QLabel();
    QMenu *leftStageMenu = new QMenu();
    QMenu *rightStageMenu = new QMenu();
    QAction *leftHoldAction = new QAction("保温阶段", this);
    QAction *leftPCRAction = new QAction("PCR阶段", this);
    QAction *leftDissolutionCurveAction = new QAction("熔解曲线阶段", this);
    QAction *rightHoldAction = new QAction("保温阶段", this);
    QAction *rightPCRAction = new QAction("PCR阶段", this);
    QAction *rightDissolutionCurveAction = new QAction("熔解曲线阶段", this);

    /* 取消反应体积输入框右键菜单 */
    ui->liquidVolume->setContextMenuPolicy(Qt::NoContextMenu);

    h->setMargin(0);
    h->setSpacing(0);

    leftStageMenu->addAction(leftHoldAction);
    leftStageMenu->addAction(leftPCRAction);
    leftStageMenu->addAction(leftDissolutionCurveAction);
    leftStageMenu->setWindowFlags(leftStageMenu->windowFlags() | Qt::FramelessWindowHint);
    leftStageMenu->setAttribute(Qt::WA_TranslucentBackground);
    leftStageMenu->setStyleSheet("QMenu{background: #fff; color: #000} QMenu::item:selected {background: rgba(0,204,255, .5)}");

    rightStageMenu->addAction(rightHoldAction);
    rightStageMenu->addAction(rightPCRAction);
    rightStageMenu->addAction(rightDissolutionCurveAction);
    rightStageMenu->setWindowFlags(rightStageMenu->windowFlags() | Qt::FramelessWindowHint);
    rightStageMenu->setAttribute(Qt::WA_TranslucentBackground);
    rightStageMenu->setStyleSheet("QMenu{background: #fff; color: #000} QMenu::item:selected {background: rgba(0,204,255, .5)}");

    leftAddStage->setIcon(QIcon(":/image/image/add_step.png"));
    deleteStage->setIcon(QIcon(":/image/image/delete_step.png"));
    rightAddStage->setIcon(QIcon(":/image/image/add_step.png"));
    leftAddStage->setStyleSheet("QPushButton {"
                                "background: none;"
                                "border: none;"
                                "}"
                                "QPushButton::menu-indicator {"
                                "image:none;"
                                "width:0px;"
                                "margin: 0;"
                                "padding: 0;"
                                "}");
    deleteStage->setStyleSheet("QPushButton {"
                               "background: none;"
                               "border: none;"
                               "margin: 0;"
                               "padding: 0;"
                               "}");
    rightAddStage->setStyleSheet("QPushButton {"
                                 "background: none; "
                                 "border: none;"
                                 "}"
                                 "QPushButton::menu-indicator {"
                                 "image:none;"
                                 "width:0px;"
                                 "margin: 0;"
                                 "padding: 0;"
                                 "}");
    leftAddStage->setIconSize(QSize(30, 30));
    rightAddStage->setIconSize(QSize(30, 30));
    deleteStage->setIconSize(QSize(30, 30));
    rightAddStage->setCursor(Qt::PointingHandCursor);
    leftAddStage->setCursor(Qt::PointingHandCursor);
    deleteStage->setCursor(Qt::PointingHandCursor);

    leftAddStage->setMenu(leftStageMenu);
    rightAddStage->setMenu(rightStageMenu);

    addStageBtnLayout->addWidget(leftAddStage);
    addStageBtnLayout->addWidget(deleteStage);
    addStageBtnLayout->addWidget(rightAddStage);
    addStageBtnLayout->setMargin(0);
    addStageBtnLayout->setSpacing(0);

    addStageContainer->setMinimumHeight(30);
    addStageContainer->setMaximumHeight(30);
    addStageContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    addStageContainer->setLayout(addStageBtnLayout);

    stepContainer->setLayout(h);
    h->setSpacing(17); // 设置控件之间的间距为17像素


    stepContainer->setObjectName("stepstage");

    footer->setMinimumHeight(40);
    footer->setMaximumHeight(40);
    footer->setStyleSheet("QWidget{background: #fff; border: none;}");
    footerLayout->setMargin(0);
    footerLayout->setSpacing(0);
    hFooter->setMargin(0);
    hFooter->setSpacing(3);

    if(stageName == PCR_STAGE){
        QLabel *text = new QLabel();
        QLabel *x = new QLabel();
        QLineEdit *cycling = new QLineEdit();
        QSpacerItem *cyclingLeftSpacer = new QSpacerItem(20, 30, QSizePolicy::Preferred);
        QSpacerItem *cyclingRightSpacer = new QSpacerItem(20, 30, QSizePolicy::Preferred);

        /* 取消循环数输入框右键菜单 */
        cycling->setContextMenuPolicy(Qt::NoContextMenu);

        /* 限制文本框输入限制 */
        /* 循环次数 */
        QRegExp cyclingrx("^[1-9]$|^[1-5][0-9]$|^6[0-4]$|^\\s*");
        QRegExpValidator *cyclingReg = new QRegExpValidator(cyclingrx, this);
        cycling->setValidator(cyclingReg);

        text->setStyleSheet("QLabel {font-family:'Alibaba PuHuiTi';font-size:16px;}");
        x->setStyleSheet("QLabel {font-family:'Alibaba PuHuiTi';font-size:16px;}");
        cycling->setStyleSheet("QLineEdit {font-family:'Alibaba PuHuiTi';font-size:16px;border: 1px solid #000;}");
        text->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
        x->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
        cycling->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        cycling->setMaximumHeight(25);
        cycling->setText(cyclingNumber);
        text->setMaximumWidth(80);
        x->setMaximumWidth(16);
        cycling->setMaximumWidth(34);
        text->setText("循环次数:");
        x->setText("x");
        hFooter->addWidget(text);
        hFooter->addWidget(cycling);
        hFooter->addWidget(x);
        cyclingContainer->setMaximumWidth(150);
        cyclingContainer->setLayout(hFooter);

        footerLayout->addItem(cyclingLeftSpacer);
        footerLayout->addWidget(cyclingContainer);
        footerLayout->addItem(cyclingRightSpacer);
        footer->setLayout(footerLayout);

        /* 发送循环数 */
        this->cyclingNumber = cyclingNumber.toInt();

        connect(cycling, &QLineEdit::editingFinished, this, [=](){
            /* 改变循环数 */
            if(cycling->text() != ""){
                procedureService->insertCycle(stageId, cycling->text());
            }
            else {
                cycling->setText("1");
                procedureService->insertCycle(stageId, "1");
            }

            totalrunningTime = procedureService->getRunTime(expId);
            runningMinute = int(totalrunningTime / 60);
            runningSecond = totalrunningTime - runningMinute*60;
            ui->EstimateTime->setText(QString::number(runningMinute) + "分" + QString::number(runningSecond) + "秒");
            /* 发送循环数 */
            /* 减去循环步骤 */
            stepCount -= this->cyclingNumber * PcrStepCount;
            this->cyclingNumber = cycling->displayText().toInt();
            stepCount += this->cyclingNumber * PcrStepCount;

            /* 通过温度差计算预计时间 */
            this->viaTempMinusToCalculateTime();
            this->cyclingNumber = cycling->text().toInt();
        });
    }
    if(stageName == DISSOLUTION_CURVE_STAGE)
        title->setStyleSheet("QLabel {"
                             "font-family:'Alibaba PuHuiTi';"
                             "font-size:22px;"
                             "color:#000;"
                             "border:none;"
                             "background:qlineargradient(spread:pad, x1:0.512, y1:1, x2:0.502, y2:0, stop:0 rgba(255, 63, 63, 255), stop:1 rgba(255, 136, 131, 255));}");
    else if(stageName == HOLDING_STAGE)
        title->setStyleSheet("QLabel {"
                             "font-family:'Alibaba PuHuiTi';"
                             "font-size:22px;"
                             "color:#000;"
                             "border:none;"
                             "background:qlineargradient(spread:pad, x1:0.522, y1:1, x2:0.507, y2:0, stop:0 rgba(125, 200, 255, 255), stop:1 rgba(121, 242, 255, 255));;}");
    else if(stageName == PCR_STAGE)
        title->setStyleSheet("QLabel {"
                             "font-family:'Alibaba PuHuiTi';"
                             "font-size:22px;"
                             "color:#000;"
                             "border:none;"
                             "background:qlineargradient(spread:pad, x1:0.537, y1:1, x2:0.522, y2:0, stop:0 rgba(60, 229, 80, 255), stop:1 rgba(160, 255, 119, 255));}");
    title->setText(stageName);
    title->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
    title->setMinimumHeight(40);
    title->setMaximumHeight(40);
    title->setObjectName("stageTitle");
    v->setMargin(0);
    v->setSpacing(0);
    v->addWidget(title);
    v->addWidget(addStageContainer);
    v->addWidget(stepContainer);
    v->addWidget(footer);


    stage->setObjectName("stage");
    stage->setGeometry(0, 0, 200, 610);
    stage->setLayout(v);
    ui->stageWidgetLayout->addWidget(stage);
    ui->stageWidgetLayout->addItem(hSpacer);

    connect(leftStageMenu, &QMenu::triggered, this, [=](QAction* a){
        procedureService->insertStage(expId, a->text(), stageOrder);
        this->renderProcedure(expId);
    });
    connect(rightStageMenu, &QMenu::triggered, this, [=](QAction* a){
        procedureService->insertStage(expId, a->text(), QString::number(stageOrder.toInt()+1));
        this->renderProcedure(expId);
    });

    connect(deleteStage, &QPushButton::clicked, this, [=](){
        if(stageCount == 1){
            deleteStage->setEnabled(false);
            return;
        }

        procedureService->deleteStage(expId, stageId, stageOrder);
        this->renderProcedure(expId);
    });
    std::tuple<QHBoxLayout*, QWidget*, QString> res;
    res = std::make_tuple(h, addStageContainer, stageName);
    return res;
}

/* 渲染扩增数据 */
void ExperimentMethodUi::renderProcedure(QString expId){

    /* 清空画布，重新渲染 */
    QList<QWidget*> p = ui->stageWidgetArea->findChildren<QWidget*>("stage");
    foreach(QWidget* pW, p){
        ui->stageWidgetLayout->removeWidget(pW);
        pW->setParent(nullptr);
        delete pW;
    }
    LOG << "渲染扩增开始！！！！！！！！！！！！！！！！";

    PcrStepCount = 0;
    stepCount = 0;
    stageCount = 0;
    /* 获取扩增数据 */
    LOG << "expId" << expId;
    procedureList = procedureService->getProcedureData(expId);
    stageList = procedureList.keys();   // 遍历所有key(阶段)
    LOG << "stageList" << stageList;
    totalrunningTime = procedureService->getRunTime(expId);
    runningMinute = int(totalrunningTime / 60);
    runningSecond = totalrunningTime - runningMinute * 60;
    ui->EstimateTime->setText(QString::number(runningMinute) + "分" + QString::number(runningSecond) + "秒");
    LOG << 1;
    /* 根据stageOrder排序阶段 */
    for(int i = 0;i < stageList.size();i ++){
        for(int j = i + 1;j < stageList.size();j ++){
            int k = stageList[i]["stage_order"].toInt();
            int l = stageList[j]["stage_order"].toInt();
            if(k > l){
                QHash<QString,QString> t = stageList[i];
                stageList[i] = stageList[j];
                stageList[j] = t;
            }
        }
    }
    LOG << 2;
    /* 遍历stageList */
    for(int i = 0; i < stageList.size(); i++){
        LOG << 3;
        stageCount++;
        /* 渲染stage */
        std::tuple<QHBoxLayout*, QWidget*, QString> stages = this->createNewStage(expId, stageList[i]["cycle_number"] , stageList[i]["name"], stageList[i]["stage_order"], stageList[i]["id"]);
        QHBoxLayout* stageLayout;
        QWidget* stepContiner;
        QString stageName;
        int stepMinSize = 0;
        std::tie(stageLayout, stepContiner, stageName) = stages;
        /* 渲染step */
        for(int j = 0; j < procedureList[stageList[i]].size(); j++){
            ProcedureStep stepInfo;
            stepMinSize += 200;
            stepInfo.QHashToStruct(procedureList[stageList[i]][j]);

            if(stageName == PCR_STAGE){
                stepCount += this->cyclingNumber;
                PcrStepCount++;
            }
            else {
                stepCount++;
            }
            this->createStep(stageLayout, stepInfo, expId, stepInfo.step_order);
            stepContiner->setMinimumWidth(stepMinSize);
        }
    }

    LOG << stepCount;



    /* 扩增曲线左右联动 */
    QList<QWidget*> stepList = ui->stageWidget->findChildren<QWidget*>("step");
    for(int i = 0; i < stepList.size(); i++){
        StageStep* s1 = (StageStep*)stepList[i];

        /* 当每一个步骤显示时，计算曲线 + 绘制波形 */
        connect(s1, &StageStep::stepShow, this, [=](){
            s1->updatePaint(s1->ui->holdStageController->value());
            /* 全局第一个阶段第一个步骤的左侧曲线 */
            if(i == 0){
                s1->leftUpdatePaint(400);
            }
        });

        if(i+1 != stepList.size()){
            StageStep* s2 = (StageStep*)stepList[i+1];

            connect(s2, StageStep::stepShow, this, [=](){
                s2->leftUpdatePaint(s1->ui->holdStageController->value());
            });

            /* 前一个步骤的滑动条数值改变，本联动滑块左侧位置改变 */
            connect(s1->ui->holdStageController, SIGNAL(valueChanged(int)), s2, SLOT(leftUpdatePaint(int)));
        }
    }

    LOG << "渲染扩增结束！！！！！！！！！！！！！！！！";

    /* 根据两个步骤的温度差，重新计算预计时间 */
    this->viaTempMinusToCalculateTime();

    /* 尺寸改变：曲线联动效果改变 */
    connect(this, &ExperimentMethodUi::sigChangeMethodWaveCascade, this, [=](){
        /* 扩增曲线左右联动 */
        QList<QWidget*> stepList = ui->stageWidget->findChildren<QWidget*>("step");
        for(int i = 0; i < stepList.size(); i++){
            StageStep* s1 = (StageStep*)stepList[i];

            /* 全局第一个阶段第一个步骤的左侧曲线 */
            if(i == 0){
                s1->leftUpdatePaint(400);
            }

            if(i+1 != stepList.size()){
                StageStep* s2 = (StageStep*)stepList[i+1];
                s2->leftUpdatePaint(s1->ui->holdStageController->value());
            }
        }
    });

}

/* 重置扩增数据 */
void ExperimentMethodUi::resetProcedure(QString expId){
    if(QMessageBox::Yes == cusMsg->show(this, CMsg::CQuestion, "重置扩增程序", "是否重置扩增程序？")){
        procedureService->restoreDefaultState(id, this->experimentType);
        /* 清空画布，重新渲染 */
        QList<QWidget*> p = ui->stageWidgetArea->findChildren<QWidget*>("stage");
        foreach(QWidget* pW, p){
            ui->stageWidgetLayout->removeWidget(pW);
            pW->setParent(nullptr);
            delete pW;
        }
        this->renderProcedure(expId);
    }
}

/* 检测荧光标记是否都为空 */
bool ExperimentMethodUi::allMarkedStatus(){
    QHash<QHash<QString,QString>,QList<QHash<QString,QString>>> procedureList = procedureService->getProcedureData(this->id);
    /* 获取所有阶段 */
    QList<QHash<QString,QString>> allStages = procedureList.keys();
    /* 遍历阶段获取步骤 */
    for(int i = 0; i < allStages.size(); i++){
        /* 获取某一阶段的所有步骤 */
        QList<QHash<QString,QString>> allSteps = procedureList[allStages[i]];
        /* 遍历所有步骤，获取所有步骤的荧光标记信息 */
        for(int j = 0; j < allSteps.size(); j++){
            if(allSteps[j]["is_fluorescence"] == "1"){
                return true;
            }
        }
    }
    return false;
}

/* 通过两侧温度差，重新计算预计时间 */
void ExperimentMethodUi::viaTempMinusToCalculateTime(){
    /* pcr阶段的父容器 */
    QWidget *pcrWidget;
    /* 所有步骤的List */
    QList<QWidget*> allStepsWithTile;

    this->totalrunningTime = procedureService->getRunTime(this->id);
    /* 获取所有阶段 */
    QList<QWidget*> stageList = ui->stageWidget->findChildren<QWidget*>("stage");
    /* 获取阶段名称 */
    QLabel* label;
    /* 获取阶段的步骤容器 */
    QWidget* stepStage;
    /* 获取该容器中所有步骤 */
    QList<QWidget*> curContainerSteps;

    for(int i = 0; i < stageList.size(); i++){
        label = (QLabel*)stageList[i]->findChild<QLabel*>("stageTitle");

        /* 如果为PCR阶段 */
        if(label->text() == PCR_STAGE){
            /* 将PCR阶段的步骤平铺开 */
            for(int j = 0; j < this->cyclingNumber; j++){
                /* 获取阶段的步骤容器 */
                stepStage = stageList[i]->findChild<QWidget*>("stepstage");
                /* 获取该容器中所有步骤 */
                curContainerSteps = stepStage->findChildren<QWidget*>("step");
                /* 添加步骤到List中 */
                for(int k = 0; k < curContainerSteps.size(); k++){
                    allStepsWithTile.append(curContainerSteps[k]);
                }
            }
        }
        /* 其他阶段 */
        else {
            /* 获取阶段的步骤容器 */
            stepStage = stageList[i]->findChild<QWidget*>("stepstage");
            /* 获取该容器中所有步骤 */
            curContainerSteps = stepStage->findChildren<QWidget*>("step");
            /* 添加步骤到List中 */
            for(int j = 0; j < curContainerSteps.size(); j++){
                allStepsWithTile.append(curContainerSteps[j]);
            }
        }
    }

    /* 遍历所有步骤，获取两边温差，进行时间计算 */
    for(int i = 1; i < allStepsWithTile.size(); i++){
        /* 获取滑动条 */
        QSlider *previousSlider = allStepsWithTile[i-1]->findChild<QSlider*>("holdStageController");
        QSlider *nextSlider = allStepsWithTile[i]->findChild<QSlider*>("holdStageController");

        int deltaTemp = nextSlider->value() - previousSlider->value();

        if(deltaTemp > 100){
            totalrunningTime += 3.2;
        }else if(deltaTemp < -100){
            totalrunningTime += 5;
        }
    }

    /* 渲染预计时间 */
    runningMinute = int(totalrunningTime / 60);
    runningSecond = int(totalrunningTime) - runningMinute * 60;
    ui->EstimateTime->setText(QString::number(runningMinute) + "分" + QString::number(runningSecond) + "秒");
}

/* 所有组件失效 */
void ExperimentMethodUi::allComponentsInvalid(){
    ui->stageWidget->setEnabled(false);
    ui->liquidVolume->setEnabled(false);
    ui->resetProcedure->setEnabled(false);
}

/* 所有组件生效 */
void ExperimentMethodUi::allComponentsValid(){
    ui->stageWidget->setEnabled(true);
    ui->liquidVolume->setEnabled(true);
    ui->resetProcedure->setEnabled(true);
}

/* 窗口改变函数 */
void ExperimentMethodUi::resizeEvent(QResizeEvent *event){
    /* 发送信号：改变曲线联动效果 */
    emit ExperimentMethodUi::sigChangeMethodWaveCascade();
}

/* 休眠函数 */
void ExperimentMethodUi::sleep(int msec){
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

